<?php
/**
 *
 */
class MyDb{
	private $db=NULL;
	
	public function __construct($host,$user,$pwd,$db){
		$this->db = @mysqli_connect($host,$user,$pwd,$db) or exit("Failed connected to the Db server.");
		$this->db->set_charset('utf8');
	}
	
	public function __destruct(){
		$this->db->close();
	}
	
	/**
	 * 直接转向mysqli原生语句
	 */
	public function __call($method, $args){
		if(in_array($method, array('autocommit','commit','rollback'))){
			@call_user_func_array(array($this->db,$method),$args);
		}else{
			exit("MyDb类中无此方法:".$method);
		}
	}
	
	/**
	 * 获取绑定参数数据类型
	 * @param	Mixed	$v	输入数据
	 * @return	String	s\d\i\b
	 */
	static function get_param_type($v){
		$type = gettype($v);
		switch($type){
			case 'string':	return 's'; break;
			case 'double':	return 'd'; break;
			case 'integer':	return 'i'; break;
			default:		return 'b';	break;
		}
	}
	
	/**
	 * 执行预处理语句
	 */
	public function stmt_sql($sql,$data = null){
		$stmt = $this->db->prepare($sql);
		if (!$stmt) {
			//var_dump($sql,$data);
			die(printf("Error: SQL语句有问题%s.\n", $stmt->sqlstate));
		}
		// 绑定参数
		if ($data != null) {
			if(is_array($data)){
				$paramType = "";
				foreach ($data as $p) {				
					$paramType .= $this->get_param_type($p);
				}
				array_unshift($data, $paramType);
			}else{
				$data = array($this->get_param_type($data),$data);
			}
			call_user_func_array(array($stmt, 'bind_param'), self::refValues($data)) or die(printf("Error: SQL语句有问题%s.\n", $stmt->error));
		}
		$stmt -> execute() or die(printf("Error: %s.\n", $stmt->error));
		global $db_query_count;
		$db_query_count += 1;
		return $stmt;
	}
	
	/**
	 * 获取查询结果Array
	 */
	public function get_all($sql,$data = null){
		$stmt = $this->stmt_sql($sql,$data);
		$variables = array(); $data = array();
		$meta = $stmt -> result_metadata();
		while ($field = $meta -> fetch_field()){
			$variables[] = &$data[$field -> name];
		}
		call_user_func_array(array($stmt, 'bind_result'), $variables);
		$i = 0; $array = array();
		while ($stmt -> fetch()) {
			$array[$i] = array();
			foreach ($data as $k => $v){
				$array[$i][$k] = $v;
			}
			$i++;
		}
		$stmt -> close();
		return $array;
	}
	
	/**
	 * 获取查询结果row
	 */
	public function get_row($sql,$data = null){
		$res = $this->get_all($sql,$data);
		return isset($res[0])?$res[0]:null;
	}
	
	/**
	 * 获取查询结果one
     * @param   string  $sql
     * @param   mixed   $data
     * @return  mixed
	 */
	public function get_one($sql,$data = null){
		$res = $this->get_row($sql,$data);
		return $res?array_shift($res):null;
	}
	
	/**
	 * 插入
	 * @return Mixed	Insert_id,失败返回false
	 */
	public function insert($sql,$data = null){
		$stmt = $this->stmt_sql($sql,$data);
		$id = $stmt->insert_id;
		$stmt -> close();
		return $id;
	}
	
	/**
	 * 更新
	 * @return Mixed	affected_rows,失败返回false
	 */
	public function update($sql,$data = null){
		$stmt = $this->stmt_sql($sql,$data);
		$affected_rows = $stmt->affected_rows;
		$stmt -> close();
		return $affected_rows;
	}
	
	/**
	 * 删除
	 */
	public function delete($sql,$data = null){
		$stmt = $this->stmt_sql($sql,$data);
		$affected_rows = $stmt->affected_rows;
		$stmt -> close();
		return $affected_rows;
	}
	
	/**
	 * 获取表全部字段
	 */
	public function show_cols($table){
		$res = $this->db->query("SHOW COLUMNS FROM ".mysqli_real_escape_string($this->db,$table));
		$arr = array();
		while($row = $res->fetch_assoc()){
			$arr []= $row;
		}
		global $db_query_count;
		$db_query_count += 1;
		return $arr;
	}
	
	/**
	 * PHP版本补丁
	 */
	static function refValues($arr){   
		if (version_compare(PHP_VERSION, '5.3.0') >= 0) {   
		    $refs = array();
		    foreach($arr as $key => $value)   
		        $refs[$key] = &$arr[$key]; 
	        return $refs;
	    }   
	    return $arr;
	}
}